package com.quick.system.service.impl;

import java.util.*;

import com.quick.common.annotation.DataScope;
import com.quick.common.annotation.DataScopeByGetInfo;
import com.quick.common.constants.Constants;
import com.quick.common.constants.DeptConstants;
import com.quick.common.core.domain.BaseEntity;
import com.quick.common.core.text.Convert;
import com.quick.common.exception.ServiceException;
import com.quick.common.utils.SecurityUtils;
import com.quick.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.quick.system.mapper.SysDeptMapper;
import com.quick.system.domain.SysDept;
import com.quick.system.service.SysDeptService;
import org.springframework.util.CollectionUtils;

/**
 * 部门Service业务层处理
 *
 * @Author: 吃素不吃肉
 * @Date: Tue Jul 25 14:14:44 CST 2023
 */
@Service
public class SysDeptServiceImpl implements SysDeptService {
    @Autowired
    private SysDeptMapper sysDeptMapper;

    /**
     * 查询部门
     *
     * @param deptId 部门主键
     * @return 部门
     */
    @Override
    @DataScopeByGetInfo(field = "deptId")
    public SysDept selectSysDeptByDeptId(Long deptId) {
        return sysDeptMapper.selectSysDeptByDeptId(deptId);
    }

    /**
     * 查询部门列表
     *
     * @param sysDept 部门
     * @return 部门
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<SysDept> selectSysDeptList(SysDept sysDept) {
        return sysDeptMapper.selectSysDeptList(sysDept);
    }

    /**
     * 新增部门
     *
     * @param sysDept 部门
     * @return 结果
     */
    @Override
    public int insertSysDept(SysDept sysDept) {
        sysDept.setCreateTime(new Date());
        sysDept.setCreateBy(SecurityUtils.getLoginUser().getUsername());
        return sysDeptMapper.insertSysDept(sysDept);
    }

    /**
     * 修改部门
     *
     * @param sysDept 部门
     * @return 结果
     */
    @Override
    @DataScopeByGetInfo(field = "deptId")
    public int updateSysDept(SysDept sysDept) {
        sysDept.setUpdateTime(new Date());
        sysDept.setUpdateBy(SecurityUtils.getLoginUser().getUsername());
        if (sysDept.getParentId().equals(sysDept.getDeptId())) {
            throw new ServiceException(StringUtils.format("修改部门{}失败，上级部门不能是自己！", sysDept.getDeptName()));
        } else if (StringUtils.equals(Constants.STATUS_DISABLE, sysDept.getStatus())
                && sysDeptMapper.selectNormalChildrenDeptById(sysDept.getDeptId()) > 0) {
            throw new ServiceException("该部门包含未停用的子部门！");
        }
        SysDept newParentDept = sysDeptMapper.selectSysDeptByDeptId(sysDept.getParentId());
        SysDept oldDept = sysDeptMapper.selectSysDeptByDeptId(sysDept.getDeptId());
        if (Objects.nonNull(newParentDept) && Objects.nonNull(oldDept)) {
            String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId();
            String oldAncestors = oldDept.getAncestors();
            sysDept.setAncestors(newAncestors);
            updateDeptChildren(sysDept.getDeptId(), newAncestors, oldAncestors);
        }
        int result = sysDeptMapper.updateSysDept(sysDept);
        if (Constants.STATUS_ENABLE.equals(sysDept.getStatus()) && StringUtils.isNotEmpty(sysDept.getAncestors())
                && !StringUtils.equals(String.valueOf(DeptConstants.TOP_DEPT_PARENT_ID), sysDept.getAncestors())) {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            updateParentDeptStatusNormal(sysDept);
        }
        return result;
    }

    /**
     * 修改该部门的父级部门状态
     *
     * @param dept 当前部门
     */
    private void updateParentDeptStatusNormal(SysDept dept) {
        String ancestors = dept.getAncestors();
        Long[] deptIds = Convert.toLongArray(ancestors);
        sysDeptMapper.updateDeptStatusNormal(deptIds);
    }

    /**
     * 修改子元素关系
     *
     * @param deptId       被修改的部门ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
        List<SysDept> children = sysDeptMapper.selectChildrenDeptById(deptId);
        for (SysDept child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            sysDeptMapper.updateDeptChildren(children);
        }
    }

    /**
     * 删除部门信息
     *
     * @param deptId 部门主键
     * @return 结果
     */
    @Override
    @DataScopeByGetInfo(field = "deptId")
    public int deleteSysDeptByDeptId(Long deptId) {
        if (sysDeptMapper.hasChildByDeptId(deptId) > 0) {
            throw new ServiceException("存在下级部门，不允许删除！");
        }
        if (sysDeptMapper.checkDeptExistUser(deptId) > 0) {
            throw new ServiceException("部门存在用户，不允许删除！");
        }
        return sysDeptMapper.deleteSysDeptByDeptId(deptId);
    }

    /**
     * 检查部门访问权限
     *
     * @param deptId 部门id
     */
    @Override
    @DataScope(deptAlias = "d")
    public void checkDeptDataScope(Long deptId) {
        List<Long> ids = sysDeptMapper.checkDeptDataScope(new BaseEntity());
        if (CollectionUtils.isEmpty(ids) || !ids.contains(deptId)) {
            throw new ServiceException("没有权限访问用户数据！");
        }
    }

    /**
     * 检查部门访问权限
     *
     * @param deptIds 部门ids
     */
    @Override
    @DataScope(deptAlias = "d")
    public void checkDeptDataScope(Long[] deptIds) {
        List<Long> ids = sysDeptMapper.checkDeptDataScope(new BaseEntity());
        if (CollectionUtils.isEmpty(ids) || !new HashSet<>(ids).containsAll(Arrays.asList(deptIds))) {
            throw new ServiceException("没有权限访问用户数据！");
        }
    }
}
